package com.ocp.socket.common.utils;

import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.ocp.socket.config.JPushConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @Author : lichong
 * @description : 极光推送工具类
 * @Date Create in 20:34 2019/5/5
 * @Modified By :
 **/
public class JPushUtil {
    private static final Logger logger = LoggerFactory.getLogger(JPushUtil.class);

    /**
     * 推送消息
     * @param notification_title        通知标题
     * @param busiCode                  业务代码  用标识是什么业务的通知
     * @param busiId                    业务对应的信息id
     * @param alias                     用户的别名
     * @return
     */
    public static PushResult pushMsgForAlias(String notification_title, String busiCode, String busiId, Integer sendNo, List<String> alias) {
        logger.info("notification_title:{}, busiCode:{}, busiId:{}, alias：{}", notification_title, busiCode, busiId, alias );
        PushResult result = null;
        JPushClient jpushClient = new JPushClient(JPushConfig.MASTER_SECRET,
                JPushConfig.APP_KEY, null, ClientConfig.getInstance());
        PushPayload payload = buildPushObject_alias_android_and_ios(notification_title, busiCode, busiId, sendNo, alias);
        try {
            result = jpushClient.sendPush(payload);
            logger.info("Got result - " + result);
        } catch (APIConnectionException e) {
            logger.error("Connection error, should retry later", e);
        } catch (APIRequestException e) {
            logger.error("Should review the error, and fix the request", e);
            logger.info("HTTP Status: " + e.getStatus());
            logger.info("Error Code: " + e.getErrorCode());
            logger.info("Error Message: " + e.getErrorMessage());
        }
        return result;
    }

    /**
     * 推送消息
     * @param notification_title        通知标题
     * @param busiCode                  业务代码  用标识是什么业务的通知
     * @param busiId                    业务对应的信息id
     * @param tags                      推送标签
     * @return
     */
    public static PushResult pushMsgForTags(String notification_title, String busiCode, String busiId, Integer sendNo, String... tags) {
        logger.info("notification_title:{}, busiCode:{}, busiId:{}, tags：{}", notification_title, busiCode, busiId, tags );
        PushResult result = null;
        JPushClient jpushClient = new JPushClient(JPushConfig.MASTER_SECRET,
                JPushConfig.APP_KEY, null, ClientConfig.getInstance());
        PushPayload payload = buildPushObject_tag_android_and_ios(notification_title, busiCode, sendNo, busiId, tags);
        try {
            result = jpushClient.sendPush(payload);
            logger.info("极光推送相应结果{}", result);
        } catch (APIConnectionException e) {
            logger.error("Connection error, should retry later", e);
        } catch (APIRequestException e) {
            logger.error("Should review the error, and fix the request", e);
            logger.info("HTTP Status: " + e.getStatus());
            logger.info("Error Code: " + e.getErrorCode());
            logger.info("Error Message: " + e.getErrorMessage());
        }
        return result;
    }

    /**
     * 获取通知定义
     * @param notification_title        通知标题
     * @param busiCode                  业务代码  用标识是什么业务的通知
     * @param busiId                    业务对应的信息id
     * @param alias
     * @return
     */
    private static PushPayload buildPushObject_alias_android_and_ios(String notification_title, String busiCode, String busiId, Integer sendNo, List<String> alias) {
        PushPayload.Builder builder = PushPayload.newBuilder();
        //设置通知平台platform   现在设定为android和ios
        builder.setPlatform(Platform.android_ios());
        //设置通知设备指定audience
        if (!CollectionUtils.isEmpty(alias)) {
            builder.setAudience(Audience.alias(alias));
        } else {
            builder.setAudience(Audience.all());
        }
        return setPayload(builder, notification_title, busiCode, busiId, sendNo);
    }

    private static PushPayload setPayload(PushPayload.Builder builder, String notification_title, String busiCode, String busiId, Integer sendNo) {
        //设备通知内容体notification
        builder.setNotification(Notification.newBuilder()
                .addPlatformNotification(AndroidNotification.newBuilder()
                        .setAlert(notification_title)
                        //.setTitle(notification_title)
                        //此字段为透传字段，不会显示在通知栏。用户可以通过此字段来做一些定制需求，如特定的key传要指定跳转的页面（value）
                        .addExtra("busiCode",busiCode).addExtra("busiId", busiId)
                        .build()
                )
                .addPlatformNotification(IosNotification.newBuilder()
                        //传一个IosAlert对象，指定apns title、title、subtitle等
                        .setAlert(notification_title)
                        //直接传alert
                        //此项是指定此推送的badge自动加1
                        .incrBadge(1)
                        //此字段的值default表示系统默认声音；传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒，
                        // 如果系统没有此音频则以系统默认声音提醒；此字段如果传空字符串，iOS9及以上的系统是无声音提醒，以下的系统是默认声音
                        .setSound("sound.caf")
                        //此字段为透传字段，不会显示在通知栏。用户可以通过此字段来做一些定制需求，如特定的key传要指定跳转的页面（value）
                        .addExtra("busiCode",busiCode).addExtra("busiId", busiId)
                        //此项说明此推送是一个background推送，想了解background看：http://docs.jpush.io/client/ios_tutorials/#ios-7-background-remote-notification
                        .setContentAvailable(true)
                        .build()
                )
                .build()
        );
        //设置推送参数
        builder.setOptions(Options.newBuilder()
                //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                .setApnsProduction(JPushConfig.APNS_PRODUCTION)
                //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                .setSendno(sendNo)
                //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                .setTimeToLive(86400)
                .build()
        );
        return builder.build();
    }

    /**
     * 获取通知定义
     * @param notification_title        通知标题
     * @param busiCode                  业务代码  用标识是什么业务的通知
     * @param busiId                    业务对应的信息id
     * @param tags                      标签
     * @return
     */
    private static PushPayload buildPushObject_tag_android_and_ios(String notification_title, String busiCode, Integer sendNo, String busiId, String... tags) {
        PushPayload.Builder builder = PushPayload.newBuilder();
        //设置通知平台platform   现在设定为android和ios
        builder.setPlatform(Platform.android_ios());
        //设置通知设备指定audience
        if (tags != null) {
            builder.setAudience(Audience.tag(tags));
        } else {
            builder.setAudience(Audience.all());
        }
        return setPayload(builder, notification_title, busiCode, busiId, sendNo);
    }

}
